<template>
  <div class="system-audit-container layout-padding">
    <el-card shadow="hover" class="layout-padding-auto">
      <div class="system-audit-search mb15">
        <el-select v-model="state.tableData.param.eventType" placeholder="请选择事件类型" clearable style="max-width: 180px">
          <el-option label="登录" value="login"></el-option>
          <el-option label="登出" value="logout"></el-option>
          <el-option label="令牌颁发" value="token_issued"></el-option>
          <el-option label="令牌撤销" value="token_revoked"></el-option>
          <el-option label="客户端创建" value="client_created"></el-option>
          <el-option label="客户端更新" value="client_updated"></el-option>
          <el-option label="客户端删除" value="client_deleted"></el-option>
          <el-option label="作用域创建" value="scope_created"></el-option>
          <el-option label="作用域更新" value="scope_updated"></el-option>
          <el-option label="作用域删除" value="scope_deleted"></el-option>
        </el-select>
        <el-input size="default" placeholder="请输入用户ID" style="max-width: 180px" v-model="state.tableData.param.userId" clearable>
        </el-input>
        <el-input size="default" placeholder="请输入客户端ID" style="max-width: 180px" v-model="state.tableData.param.clientId" clearable>
        </el-input>
        <el-select v-model="state.tableData.param.success" placeholder="请选择结果" clearable style="max-width: 180px">
          <el-option label="成功" :value="true"></el-option>
          <el-option label="失败" :value="false"></el-option>
        </el-select>
        <el-date-picker
          v-model="state.dateRange"
          type="datetimerange"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DDTHH:mm:ss.sssZ"
          @change="handleDateRangeChange"
          style="max-width: 350px"
        />
        <el-button size="default" type="primary" class="ml10" @click="getTableData">
          <el-icon>
            <ele-Search />
          </el-icon>
          查询
        </el-button>
        <el-button size="default" type="success" class="ml10" @click="onExportLogs">
          <el-icon>
            <ele-Download />
          </el-icon>
          导出
        </el-button>
      </div>
      <el-table :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%">
        <el-table-column type="index" label="序号" width="60" />
        <el-table-column prop="eventType" label="事件类型" show-overflow-tooltip>
          <template #default="scope">
            <el-tag :type="getEventTypeTagType(scope.row.eventType)" size="small">
              {{ getEventTypeText(scope.row.eventType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="username" label="用户名" show-overflow-tooltip></el-table-column>
        <el-table-column prop="clientId" label="客户端ID" show-overflow-tooltip></el-table-column>
        <el-table-column prop="ipAddress" label="IP地址" show-overflow-tooltip></el-table-column>
        <el-table-column prop="success" label="结果" show-overflow-tooltip>
          <template #default="scope">
            <el-tag :type="scope.row.success ? 'success' : 'danger'" size="small">
              {{ scope.row.success ? '成功' : '失败' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="timestamp" label="时间" show-overflow-tooltip></el-table-column>
        <el-table-column label="操作" width="100">
          <template #default="scope">
            <el-button size="small" text type="primary" @click="onViewLogDetail(scope.row)">
              <el-icon>
                <ele-View />
              </el-icon>
              详情
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        @size-change="onHandleSizeChange"
        @current-change="onHandleCurrentChange"
        class="mt15"
        :pager-count="5"
        :page-sizes="[10, 20, 30, 50]"
        v-model:current-page="state.tableData.param.page"
        background
        v-model:page-size="state.tableData.param.size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="state.tableData.total"
      >
      </el-pagination>
    </el-card>
    
    <!-- 日志详情对话框 -->
    <el-dialog title="审计日志详情" v-model="state.logDetailDialog.visible" width="800px">
      <div v-if="state.logDetailDialog.data" class="log-detail">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="事件类型">
            <el-tag :type="getEventTypeTagType(state.logDetailDialog.data.eventType)">
              {{ getEventTypeText(state.logDetailDialog.data.eventType) }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="结果">
            <el-tag :type="state.logDetailDialog.data.success ? 'success' : 'danger'">
              {{ state.logDetailDialog.data.success ? '成功' : '失败' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="用户名">
            {{ state.logDetailDialog.data.username || '-' }}
          </el-descriptions-item>
          <el-descriptions-item label="用户ID">
            {{ state.logDetailDialog.data.userId || '-' }}
          </el-descriptions-item>
          <el-descriptions-item label="客户端ID">
            {{ state.logDetailDialog.data.clientId || '-' }}
          </el-descriptions-item>
          <el-descriptions-item label="IP地址">
            {{ state.logDetailDialog.data.ipAddress }}
          </el-descriptions-item>
          <el-descriptions-item label="时间" :span="2">
            {{ state.logDetailDialog.data.timestamp }}
          </el-descriptions-item>
          <el-descriptions-item label="用户代理" :span="2">
            <div class="user-agent">{{ state.logDetailDialog.data.userAgent }}</div>
          </el-descriptions-item>
          <el-descriptions-item v-if="!state.logDetailDialog.data.success" label="错误信息" :span="2">
            <div class="error-msg">{{ state.logDetailDialog.data.errorMsg }}</div>
          </el-descriptions-item>
        </el-descriptions>
        
        <div v-if="state.logDetailDialog.data.details" class="details-section mt20">
          <h4>详细信息</h4>
          <el-card class="details-card">
            <pre class="details-content">{{ JSON.stringify(state.logDetailDialog.data.details, null, 2) }}</pre>
          </el-card>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="state.logDetailDialog.visible = false">关 闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="oidcAudit">
import { reactive, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { getAuditLogList, exportAuditLogs } from '/@/api/oidc/audit';

// 定义变量内容
const state = reactive({
  tableData: {
    data: [],
    total: 0,
    loading: false,
    param: {
      page: 1,
      size: 10,
      eventType: '',
    userId: '',
    clientId: '',
      success: '',
      start_time: '',
      end_time: '',
    },
  },
  dateRange: [],
  logDetailDialog: {
    visible: false,
    data: null,
  },
});

// 获取事件类型文本
const getEventTypeText = (eventType: string) => {
  const eventTypeMap = {
    login: '登录',
    logout: '登出',
    token_issued: '令牌颁发',
    token_revoked: '令牌撤销',
    client_created: '客户端创建',
    client_updated: '客户端更新',
    client_deleted: '客户端删除',
    scope_created: '作用域创建',
    scope_updated: '作用域更新',
    scope_deleted: '作用域删除',
  };
  return eventTypeMap[eventType] || eventType;
};

// 获取事件类型标签类型
const getEventTypeTagType = (eventType: string) => {
  const typeMap = {
    login: 'success',
    logout: 'info',
    token_issued: 'primary',
    token_revoked: 'warning',
    client_created: 'success',
    client_updated: 'primary',
    client_deleted: 'danger',
    scope_created: 'success',
    scope_updated: 'primary',
    scope_deleted: 'danger',
  };
  return typeMap[eventType] || 'info';
};

// 处理日期范围变化
const handleDateRangeChange = (dateRange: any) => {
  if (dateRange && dateRange.length === 2) {
    state.tableData.param.start_time = dateRange[0];
    state.tableData.param.end_time = dateRange[1];
  } else {
    state.tableData.param.start_time = '';
    state.tableData.param.end_time = '';
  }
};

// 初始化表格数据
const getTableData = () => {
  state.tableData.loading = true;
  getAuditLogList(state.tableData.param)
    .then((res: any) => {
      state.tableData.data = res.data.items;
      state.tableData.total = res.data.total;
    })
    .finally(() => {
      state.tableData.loading = false;
    });
};

// 查看日志详情
const onViewLogDetail = (row: any) => {
  state.logDetailDialog.data = row;
  state.logDetailDialog.visible = true;
};

// 导出日志
const onExportLogs = () => {
  const params = { ...state.tableData.param };
  delete params.page;
  delete params.size;
  
  exportAuditLogs(params)
    .then((res: any) => {
      // 创建下载链接
      const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `audit_logs_${new Date().getTime()}.xlsx`;
      link.click();
      window.URL.revokeObjectURL(url);
      ElMessage.success('导出成功');
    })
    .catch(() => {
      ElMessage.error('导出失败');
    });
};

// 分页改变
const onHandleSizeChange = (val: number) => {
  state.tableData.param.size = val;
  getTableData();
};

// 分页改变
const onHandleCurrentChange = (val: number) => {
  state.tableData.param.page = val;
  getTableData();
};

// 页面加载时
onMounted(() => {
  getTableData();
});
</script>

<style scoped lang="scss">
.system-audit-container {
  .system-audit-search {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 10px;
  }
  
  .log-detail {
    .user-agent {
      word-break: break-all;
      font-size: 12px;
      color: #666;
    }
    
    .error-msg {
      color: #f56c6c;
      font-size: 12px;
    }
    
    .details-section {
      h4 {
        margin-bottom: 10px;
        color: #303133;
      }
      
      .details-card {
        background-color: #f8f9fa;
        
        .details-content {
          margin: 0;
          font-size: 12px;
          color: #606266;
          white-space: pre-wrap;
          word-break: break-all;
          max-height: 300px;
          overflow-y: auto;
        }
      }
    }
  }
}
</style>